home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 10
/
FM Towns Free Software Collection 10.iso
/
ms_dos
/
tool
/
fwcp
/
src
/
more.c
< prev
next >
Wrap
Text File
|
1995-03-31
|
6KB
|
346 lines
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <ctype.h>
#include <jctype.h>
#include <string.h>
#include "defs.h"
#include "key.h"
#define TAB 8
#define READMAX 4096
typedef struct _LP {
struct _LP *next;
struct _LP *back;
char line[1];
} LINPTR;
static FILE *fp;
static LINPTR *now;
static int line = (-1);
static int top = 0;
static int scan = 0;
static int text_mode = TRUE;
static unsigned long addr = 0L;
static int read_pos = 0;
static int read_max = 0;
static unsigned char read_buf[READMAX];
static void readinit()
{
int n;
int len = 0;
addr = 0L;
read_pos = 0;
read_max = fread(read_buf, 1, READMAX, fp);
for ( n = 0 ; n < read_max ; n++ ) {
switch(read_buf[n]) {
case '\n': case '\r': case '\t': case '\f': case '\b':
break;
case 0x7F: case 0xFE: case 0xFF:
len++;
break;
default:
if ( read_buf[n] < ' ' )
len++;
break;
}
}
text_mode = (len > 10 ? FALSE : TRUE);
}
static int readchar()
{
if ( read_pos >= read_max ) {
read_pos = 0;
if ( (read_max = fread(read_buf, 1, READMAX, fp)) <= 0 )
return EOF;
}
return (read_buf[read_pos++]);
}
static LINPTR *readline()
{
int n;
int ch;
int len = 0;
LINPTR *lp;
unsigned char *p;
char buf[LINSIZ];
if ( text_mode == FALSE ) {
/********
01234567890123456789012345678901234567890123456789012345678901234567890123456
00000000 00 01 02 03 04 05 06 07 - 08 09 0a 0b 0c 0d 0e 0f 0123456789abcdef
*********/
sprintf(buf, "%08lx ", addr);
len = 9;
p = buf + 61;
for ( n = 0 ; n < 16 ; n++ ) {
if ( (ch = readchar()) == EOF )
break;
sprintf(buf + len, "%s%02x", (n == 8 ? " - " : " "), ch);
len += strlen(buf + len);
if ( ch < ' ' || ch == 0x7F )
ch = '.';
*(p++) = ch;
}
if ( n == 0 )
return NULL;
while ( len < 61 )
buf[len++] = ' ';
len = (p - buf);
*p = '\0';
for ( p = buf + 61 ; *p != '\0' ; p++ ) {
if ( iskanji(p[0]) ) {
if ( iskanji2(p[1]) )
p++;
else
p[0] = '.';
} else if ( (p[0] >= 0x80 && p[0] <= 0x9F) ||
(p[0] >= 0xE0 && p[0] <= 0xFF) )
p[0] = '.';
}
addr += 16;
} else {
while ( len < SCR_X && (ch = readchar()) != EOF ) {
if ( iskanji(ch) ) {
if ( len >= (SCR_X - 1) ) {
read_pos--;
break;
}
buf[len++] = ch;
if ( (ch = readchar()) == EOF ) {
len--;
break;
}
buf[len++] = ch;
} else if ( ch == '\t' ) {
n = TAB - (len % TAB);
while ( len < SCR_X && n-- > 0 )
buf[len++] = ' ';
} else if ( ch == '\n' ) {
break;
} else if ( ch != '\r' && ch != 0x1A )
buf[len++] = ch;
}
}
buf[len] = '\0';
if ( len == 0 && ch == EOF )
return NULL;
if ( (lp = (LINPTR *)malloc(sizeof(LINPTR) + len)) == NULL )
return NULL;
lp->next = lp->back = NULL;
strcpy(lp->line, buf);
return lp;
}
char *getline(int no)
{
while ( no < line ) {
if ( now->back == NULL )
return NULL;
now = now->back;
line--;
}
while ( no > line ) {
if ( now->next == NULL ) {
if ( (now->next = readline()) == NULL )
return NULL;
now->next->back = now;
}
now = now->next;
line++;
}
return now->line;
}
int putline(int y, int no)
{
char *p;
LOCATE(0, y);
if ( (p = getline(no)) != NULL ) {
PUTS(p);
if ( strlen(p) < SCR_X )
ERALINE();
return FALSE;
} else {
ERALINE();
return ERR;
}
}
void forscrool()
{
if ( getline(top + (SCR_Y - 1)) == NULL )
return;
top++;
FORSCROOL();
putline(SCR_Y - 2, line);
LOCATE(0, SCR_Y - 1);
/**********
FLUSH();
***********/
}
void backscrool()
{
if ( top <= 0 )
return;
top--;
BAKSCROOL();
putline(0, top);
LOCATE(0, SCR_Y - 1);
ERALINE();
/*************
FLUSH();
**************/
}
int more(char *file)
{
int n, ch;
LINPTR *lp;
char *p;
char buf[128 + 2];
if ( (fp = fopen(file, "rb")) == NULL )
return ERR;
line = top = 0;
readinit();
if ( (now = readline()) == NULL ) {
fclose(fp);
return ERR;
}
SAVESCREEN();
for ( n = 0 ; n < (SCR_Y - 1) ; n++ )
putline(n, n);
LOCATE(0, n);
ERALINE();
FLUSH();
buf[0] = '\0';
for ( ; ; ) {
ch = GETCH();
switch(ch) {
case K_ABORT:
case K_END_OF:
case 'Q': case 'q':
goto ENDOF;
case ' ':
for ( n = 0 ; n < (SCR_Y - 3) ; n++ )
forscrool();
break;
case K_BACK_SPC:
for ( n = 0 ; n < (SCR_Y - 3) ; n++ )
backscrool();
break;
case K_UP_NODE:
backscrool();
break;
case K_DOWN_NODE:
case K_END_LINE:
forscrool();
break;
case K_SCREEN_FLUSH:
REDISP:
for ( n = 0 ; n < (SCR_Y - 1) ; n++ )
putline(n, top + n);
LOCATE(0, SCR_Y - 1);
break;
case 'n': case 'N':
SERCH:
if ( buf[0] == '\0' )
break;
LOCATE(0, SCR_Y - 1);
FPUTS("/%-78.78s", buf);
ERALINE();
for ( n = scan + 1; ; n++ ) {
if ( (p = getline(n)) == NULL )
break;
else if ( strstr(p, buf) != NULL ) {
if ( (scan = top = n) > 10 )
top -= 10;
goto REDISP;
}
}
NOTFOUND:
scan = 0;
BEEP();
LOCATE(0, SCR_Y - 1);
FPUTS("not found %s", buf);
LOCATE(0, SCR_Y - 1);
break;
case 'p': case 'P':
if ( buf[0] == '\0' )
break;
LOCATE(0, SCR_Y - 1);
FPUTS("/%-78.78s", buf);
ERALINE();
for ( n = scan - 1 ; n > 0 ; n-- ) {
if ( (p = getline(n)) == NULL )
break;
else if ( strstr(p, buf) != NULL ) {
if ( (scan = top = n) > 10 )
top -= 10;
goto REDISP;
}
}
goto NOTFOUND;
case '/':
LOCATE(0, SCR_Y - 1);
PUTS("/");
for ( ; ; ) {
ch = input(1, SCR_Y - 1, 78, 128, 0, buf);
if ( ch == K_END_LINE )
goto SERCH;
}
LOCATE(0, SCR_Y - 1);
ERALINE();
break;
}
FLUSH();
}
ENDOF:
fclose(fp);
while ( now->back != NULL )
now = now->back;
while ( (lp = now) != NULL ) {
now = now->next;
free(lp);
}
LOADSCREEN();
FLUSH();
return FALSE;
}